/* 
 * File:   Manager.cpp
 * Author: niyaz
 * 
 * Created on 22 Февраль 2011 г., 10:44
 */
#include <iostream>
#include <time.h>
#include <vector>

#include "Manager.h"
#include "LocalSource.h"
#include "RemoteSource.h"
#include "File.h"
#include "MyDate.h"
#include "Log.h"

using namespace std;

void
Manager::doRecSenSyn (int what)
{

  Log::getInstance ()->sDebugging ("Manager::doRecSenSyn");

  local_source.Connect ();
  std::vector<File> local_files = local_source.getLocalFiles ();


  Log::getInstance ()->sMessage ("\tLocal files");
  for (int i = 0; i != local_files.size (); ++i)
    {
      string buf = "\t\t"+local_files[i].name +" "+ local_files[i].date.getstring ();
      Log::getInstance ()->sMessage (buf);
    }


  remote_source.rConnect ();
  if (remote_source.rConnected ())
    Log::getInstance ()->sMessage ("\tConnected to remote source to take list of files");
  else
    throw "Can't connect";

  std::vector<File> remote_files = remote_source.getRemoteFiles ();


  Log::getInstance ()->sMessage ("\tRemote files");
  for (int i = 0; i != remote_files.size (); ++i)
    {
      string buf = "\t\t"+remote_files[i].name +" "+ remote_files[i].date.getstring ();
      Log::getInstance ()->sMessage (buf);

    }


  for (int i = 0; i != remote_files.size (); ++i)
    {
      remote_files.at (i).full_local_path = local_source.getLocalPath () + remote_files.at (i).name ;
      remote_files.at (i).path_only = local_source.getLocalPath () ;
    }


  switch (what)
    {
    case 1:
      strategyReceive(local_files,remote_files);
      break;
    case 2:
      strategySend(local_files,remote_files);
      break;
    case 3:
      strategySynch(local_files,remote_files);
      break;
    default:
      throw "wrong int parameter for RecSenSyn";
    }

  Log::getInstance ()->sMessage ("\tActions with local files");
  for (int i = 0; i != local_files.size (); ++i)
    {

      string s = "!!!!!!";
      if (local_files[i].action == SEND)
        s = "SEND";
      if (local_files[i].action == NOTHING)
        s = "NOTHING";
      if (local_files[i].action == REMOVE)
        s = "REMOVE";
      if (local_files[i].action == RECEIVE)
        s = "RECEIVE";

      string buf = "\t\t"+local_files[i].name +" "+ s;
      Log::getInstance ()->sMessage (buf);
    }

  Log::getInstance ()->sMessage ("\tActions with remote files");

  for (int i = 0; i != remote_files.size (); ++i)
    {
      string s = "!!!!!!";
      if (remote_files[i].action == SEND)
        s = "SEND";
      if (remote_files[i].action == NOTHING)
        s = "NOTHING";
      if (remote_files[i].action == REMOVE)
        s = "REMOVE";
      if (remote_files[i].action == RECEIVE)
        s = "RECEIVE";

      string buf = "\t\t"+remote_files[i].name +" "+ s;
      Log::getInstance ()->sMessage (buf);
    }


  remote_source.sConnect ();
  if (remote_source.sConnected ())
    Log::getInstance ()->sMessage ("\tConnected to remote source to send files");
  else
    throw "Can't connect to send";

  remote_source.preCleaning (remote_files);
  local_source.preCleaning  (local_files);
 
  local_source.preArchivingStuff (local_files,remote_files);

  remote_source.setFileActions (local_files);
  remote_source.setFileActions (remote_files);
  
  local_source.postArchivingStuff (local_files,remote_files);

};

std::vector<File>
Manager::doRView ()
{


  Log::getInstance ()->sDebugging ("Manager: doing remote view");
  remote_source.rConnect ();


  if (remote_source.rConnected ())
    Log::getInstance ()->sMessage ("Connected to remote source");
  else
    throw "Can't connect";

  std::vector<File> remote_files = remote_source.getRemoteFiles ();
  if (remote_files.size ())
    Log::getInstance ()->sMessage ("Remote Files:");
  else
    Log::getInstance ()->sMessage ("There are not remote files");

  for (int i = 0; i != remote_files.size (); ++i)
    {
      string buf = remote_files.at(i).name + " " + remote_files.at (i).date.getstring ();
      if (remote_files.at (i).if_archive)
          buf+=" archive";
      if (remote_files.at (i).if_synch)
          buf+=" synch";
      if ((!remote_files.at (i).if_archive) && (!remote_files.at (i).if_synch))
        buf+=" simple";
      Log::getInstance ()->sMessage (buf);
    }
  return remote_files;

};

std::vector<File>
        Manager::doLView()
{
     Log::getInstance ()->sDebugging ("Manager::doLView");
     local_source.Connect ();
     std::vector<File> local_files = local_source.getLocalFiles ();

     if (local_files.size ())
    Log::getInstance ()->sMessage ("Remote Files:");
  else
    Log::getInstance ()->sMessage ("There are not remote files");

  for (int i = 0; i != local_files.size (); ++i)
    {
      string buf = local_files.at(i).name + " " + local_files.at (i).date.getstring ();
      if (local_files.at (i).if_archive)
          buf+=" archive";
      if (local_files.at (i).if_synch)
          buf+=" synch";
      if ((!local_files.at (i).if_archive) && (!local_files.at (i).if_synch))
        buf+=" simple";
      Log::getInstance ()->sMessage (buf);
    }
  return local_files;
}

void
Manager::doRClear ()
{
  Log::getInstance ()->sDebugging ("Manager: Started trying to rclear");
  remote_source.rConnect ();
  if (remote_source.rConnected ())
    Log::getInstance ()->sMessage ("Connected to remote source");
  else
    throw "Can't connect";

  std::vector<File> remote_files = remote_source.getRemoteFiles ();

  Log::getInstance ()->sDebugging ("Manager: Took remote files.");
  for (int i = 0; i != remote_files.size (); ++i)
    {
      remote_files[i].action = REMOVE;
    }
  Log::getInstance ()->sDebugging ("Manager:try to execute actions");
  remote_source.setFileActions (remote_files);
  Log::getInstance ()->sMessage ("Have cleaned");
};
void
       Manager::doLClear()
{
   Log::getInstance ()->sDebugging ("Manager: Started trying to rclear");
  local_source.Connect ();
  std::vector<File> local_files = local_source.getLocalFiles();

  Log::getInstance ()->sDebugging ("Manager: Took remote files.");
  for (int i = 0; i != local_files.size (); ++i)
    {
      local_files[i].action = REMOVE;
    }
  Log::getInstance ()->sDebugging ("Manager:try to execute actions");
 local_source.preCleaning(local_files);
  Log::getInstance ()->sMessage ("Have cleaned");
}

void
Manager::doRDelete ()
{
  bool l = false;
  Log::getInstance ()->sDebugging ("Manager: Started trying to rdelete ");
  remote_source.rConnect ();

  if (remote_source.rConnected ())
    Log::getInstance ()->sMessage ("Connected to remote source");
  else
    throw "Can't connect";

  std::vector<File> remote_files = remote_source.getRemoteFiles ();

  Log::getInstance ()->sDebugging ("\tTook remote files. Trying do match.");
  for (int i = 0; i != remote_files.size (); ++i)
    {
      if (remote_files.at (i).name == account.receive_adress.adv_adr)
        {
          remote_files[i].action = REMOVE;
          l = true;
        }
      else
        remote_files[i].action = NOTHING;
    }
  Log::getInstance ()->sDebugging ("\t\t Ended mathcing. try to execute actions");
  remote_source.setFileActions (remote_files);

  if (l)
    Log::getInstance ()->sMessage ("Sucsessfully deleted");
  else
    throw "Not such file";
};



void
Manager::doLDelete ()
{
    bool l = false;
  Log::getInstance ()->sDebugging ("Manager: Started trying to rdelete ");
  local_source.Connect ();

  std::vector<File> local_files = local_source.getLocalFiles();

  Log::getInstance ()->sDebugging ("\tTook remote files. Trying do match.");
  for (int i = 0; i != local_files.size (); ++i)
          local_files[i].action = REMOVE;

  Log::getInstance ()->sDebugging ("\t\t Ended mathcing. try to execute actions");
  local_source.preCleaning(local_files);

  if (l)
    Log::getInstance ()->sMessage ("Sucsessfully deleted");
  else
    throw "Not such file";
};




void Manager::strategyReceive (std::vector<File>& local_files_, std::vector<File>& remote_files_)
{
   for (int i = 0; i != remote_files_.size (); ++i)
    {
      remote_files_.at (i).action = RECEIVE;
      for (int j = 0; j != local_files_.size (); ++j)
        if (local_files_[j].name == remote_files_[i].name)
          {
            if (local_files_[j].date > remote_files_[i].date)
              remote_files_[i].action = NOTHING;
            else
              local_files_[j].action = REMOVE;
            break;
          }
    };
};

void Manager::strategySend (std::vector<File>& local_files_, std::vector<File>& remote_files_)
{
    for (int i = 0; i != local_files_.size (); ++i)
    {
      local_files_.at (i).action = SEND;
      for (int j = 0; j != remote_files_.size (); ++j)
        if (local_files_[i].name == remote_files_[j].name)
          {
            if (local_files_[i].date < remote_files_[j].date)
              local_files_[i].action = NOTHING;
            else
              remote_files_[j].action = REMOVE;
            break;
          }
    }
};

void Manager::strategySynch (std::vector<File>& local_files_, std::vector<File>& remote_files_)
{
  local_files_[0].action = SEND;
  for (int i = 0; i != remote_files_.size (); ++i)
    {
      remote_files_[i].action = NOTHING;
      if (remote_files_[i].name == local_files_[0].synch_name) 
        {
          cout << "for some reason i'm here" << endl;
          if (remote_files_[i].date < local_files_[0].date)
            {
              remote_files_[i].action = REMOVE;
              local_files_[0].action = SEND;
            }
          else
            {
              remote_files_[i].action = RECEIVE;
              local_files_[0].action = REMOVE;
            };
          break;
        }
    }
};
















